Fork me on GitHub

SpringMVC

注意:所有文章除特别说明外,转载请注明出处.

第4章 Spring MVC

[TOC]

4.1 Spring MVC 概述

MVC模式

在我们使用Spring MVC的时候,需要我们在web.xml文件中配置DispatcherServlet,该DispatcherServerlet可以看做是一个前端控制器的具体实现,还需要在Bean定义中配置Web请求和Controller的对应关系,以及各种视图的展现方式。在具体使用Controller的时候,会看到ModelAndView数据的生成,还会看到将ModelAndView数据交给相应的View来进行呈现。

4.2 Web环境中的Spring MVC

Spring MVC 是建立在IoC容器基础上的,要了解SpringMVC,首先要了解 Spring IoC 是如何在Web环境中发挥作用的。

Spring IoC是个独立的模块,并不是直接在Web环境中发挥作用。如果我们需要在Web环境中使用IOC容器,需要为IOC设计一个启动过程,将ioc容器导入。在web容器启动过程中,将IoC导入,并在web容器中建立起来并初始化,这样才能建立起 Spring MVC 运行机制,从而响应web容器传递的HTTP请求。

我们通常在web.xml文件中可以得到通常的配置。

  1. 首选是定义一个Servlet对象,它是Spring MVC的DispatcherServlet。该DispatcherServlet是MVC中最重要的一个类,起着分发请求的作用。

  2. 然后为这个DispatcherServlet定义了对应的URL映射,这些URL映射为这个Servlet指定了需要处理的HTTP请求。context-param参数的配置用来指定Spring IOC容器读取Bean定义的XML文件的路径,在这里,这个配置文件被定义为/WEB-INF/applicationContext.xml。

  3. 最后ContextLoaderListener被定义为一个监听器,该监听器是与Web服务器的生命周期相关联的,由ContextLoaderListener监听器负责完成IOC容器在Web环境中的启动工作。

DispatcherServlet和ContextLoaderListener提供了在Web容器中对Spring的接口,这些接口与web容器耦合是通过 ServletContext 来实现的。

4.3 上下文在Web容器中的启动

4.3.1 IOC容器启动的基本过程

IoC容器启动过程就是建立上下文的过程,该上下文与ServletContext相伴而生,由ContextLoaderListener启动的上下文为根上下文。在根上下文的基础上,还有一个与Web MVC相关的上下文用来保存控制器(DispatcherServlet)需要的MVC对象,作为跟上下文的子上下文。

在web.xml中,已经配置了由Spring提供的实现了ServletContextListener接口的ContextLoaderListener,该监听器类为在Web容器中建立IoC容器提供服务。

在Web容器中,建立WebApplicationContext的过程,是在contextInitialized的接口实现中完成的。

具体的载入IOC容器的过程是由ContextLoaderListenser交由ContextLoader来完成的,而ContextLoader本身就是ContextLoaderListener的基类。

在ContextLoader中,完成两个IoC容器建立的基本过程,一个是在Web容器中建立起双亲IoC容器,另一个是生成相应的WebApplicationContext并将其初始化。

4.3.2 Web容器中的上下文设计

在启动过程中,Spring使用默认的XmlWebApplicationContext 实现作为IoC容器。

4.3.3 ContextLoader的设计与实现

对于Spring承载的Web应用而言,可以指定在Web应用程序启动时载人IoC容器(或者称为WebAppl icationContext)。这个功能是由ContextLoaderListener这样的类来完成的,它是在Web容器中配置的监听器。这个ContextLoaderListener通过使用ContextLoader来完成实际的WebApplicationContext,也就是IoC容器的初始化工作。这个ContextLoader就像Spring应用程序在Web容器中的启动器。这个启动过程是在Web容器中发生的,所以需要根据Web容器部署的要求来定义ContextLoader。

在初始化这个上下文以后,该上下文会被存储到SevletContext中,这样就建立了一个全局的关于整个应用的上下文。同时,在启动Spring MVC时.我们还会看到这个上下文被以后的DispatcherServlet在进行自己持有的上下文的初始化时,设置为DispatcherServlet自带的上下文的双亲上下文。

4.4 Spring MVC 的设计与实现

4.4.1 Spring MVC的应用场景

在web.xml中,除了需要配置ContextLoaderListener之外,还需要配置DispatcherServlet。建立Spring的上下文体系并初始化。

在完成对ContextLoaderListener的初始化以后,Web容器开始初始化DispatcherServlet,这个初始化的启动与在web.xml中对载入次序的定义有关。

DispatcherServiet会建立自己的上下文来持有 Spring MVC 的 Bean 对象,在建立这个自己持有的Ioc容器时,会从ServletContext中得到根上下文作为DispatcherServlet持有上下文的双亲上下文。有了这个根上下文,再对自己持有的上下文进行初始化,最后把自己持有的这个上下文保存到ServletContext(Web容器的上下文)中,供以后检索和使用。

4.4.2 Spring MVC设计概览

DispatcherServlet的处理过程

DispatcherServiet的工作大致可以分为两个部分:

  1. 由initServletBean()启动,通过initWebAppIicationContext()方法最终调用DispatcherServlet的initStrategies方法。在这个方法里,DispatcherServlet对MVC模块的其他部分进行了初始化,比如handlerMapping, ViewResolver等。
  2. 对HTTP请求进行响应,作为一个Serviet,Web容器会调用Servlet的doGet()和doPost()方法,在经过FrameworkServlet的processRequest()简单处理后,会调用DispatcherServlet的doService()方法,在这个方法调用中封装了doDispatch(),这个doDispatch()是Dispatcher实现MVC模式的主要部分。

4.4.3 DispatcherServlet的启动和初始化

4.4.4 MVC处理HTTP分发请求

1.HandlerMapping的配置和设计原理

在初始化完成时,在上下文环境中已定义的所有HandlerMapping都已经被加载了,这些加载的handlerMappings被放在一个List中并排序,存储着HTTP请求对应的映射数据。这个List中的每一个元素都对应着一个具体handlerMapping的配置,一般每一个handlerMapping可以持有一系列从URL请求到Controller的映射,而Spring MVC 提供了一系列的HandlerMapping实现。

2.使用HandlerMapping完成请求的映射处理

通过SimpleUrlHandlerMapping的实现来分析HandlerMapping的接口方法getHandler,该方法会根据初始化时得到的映射关系来生成DispatcherServlet需要的HandlerExecutionChain,也就是说,这个getHandler方法是实际使用HandlerMapping完成请求的映射处理的地方。

获得handler的具体过程在getHandlerInternal方法中实现,这个方法接受HTTP请求作为参数,它的实现在AbstractHandlerMapping的子类AbstractUrlHandlerMapping中,这个实现过程包括从HTTP请求中得到URL,并根据URL到urlMapping中获得handler。

经过这一系列对HTTP请求进行解析和匹配handler的过程,得到了与请求对应的handler处理器。在返回的handler中,已经完成了在HandlerExecutionChain中的封装工作,为handler对HTTP请求的响应做好了准备。

接下来就是解决请求如何实现分发的问题,从而得到对应的handler。

3.Spring MVC对HTTP请求的分发处理

4.5 Spring MVC 视图的呈现

4.5.1 DispatcherServlet视图呈现的设计

本文标题:SpringMVC

文章作者:Bangjin-Hu

发布时间:2019年10月15日 - 09:22:26

最后更新:2020年03月30日 - 08:18:18

原始链接:http://bangjinhu.github.io/undefined/第4章 Spring MVC/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Bangjin-Hu wechat
欢迎扫码关注微信公众号,订阅我的微信公众号.
坚持原创技术分享,您的支持是我创作的动力.